package com.googlecode.lohr.tools.language;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

import lohr.lang.dom.CompilationUnit;
import lohr.lang.dom.TypeBinding;
import lohr.lang.dom.TypeReference;

import org.eclipse.jdt.core.dom.AST;

import com.googlecode.lingwah.ParseContext;
import com.googlecode.lingwah.ParseResults;
import com.googlecode.lohr.utils.IOUtils;


/**
 * lohr is compiled to Java code.
 * This class takes a lohr DOM document and generates a Java DOM document.
 * This class uses the Eclipse org.eclipse.jdt.core.dom API to represent 
 * a Java document.
 * 
 * Compilation has two phases, a pre-processing step and a code generation step.
 * 
 * The actual work of translating a lohr DOM document into a Java DOM document is done 
 * by instances of PreProcessor and JavaGenerator.
 * Third parties may implement their own lohr pre-processors and 
 * code generators and plug them into the lohr compiler.
 * 
 * The easiest way to compile is...
 * 	javaCompilationUnit= LohrCompiler.compile(lohrCompilationUnit);
 * 
 * @author ted.stockwell
 */
public class LohrCompiler {
	
	static public Collection<org.eclipse.jdt.core.dom.CompilationUnit> compile(lohr.lang.dom.CompilationUnit lohrCompilationUnit) {
		return new LohrCompiler(lohrCompilationUnit).getGenerated();
	}
	
	static public Collection<org.eclipse.jdt.core.dom.CompilationUnit> compile(File file) throws IOException {
		String text= new String(IOUtils.readFully(file));
		ParseContext context= new ParseContext(text);
		ParseResults results= context.getParseResults(LohrGrammar.DEFINITION.CompilationUnit, 0);
		CompilationUnit compilationUnit= (CompilationUnit) LohrDOMBuilder.process(results);
		compilationUnit.setFile(file);
		return compile(compilationUnit); 
	}


	lohr.lang.dom.CompilationUnit _source;
	ArrayList<org.eclipse.jdt.core.dom.CompilationUnit> _generated= new ArrayList<org.eclipse.jdt.core.dom.CompilationUnit>();
	
	private ArrayList<JavaGenerator> _generators= new ArrayList<JavaGenerator>();
	private ArrayList<LohrPreProcessor> _preprocessors= new ArrayList<LohrPreProcessor>();
	private AST _ast= AST.newAST(AST.JLS4);
	
	
	public LohrCompiler(lohr.lang.dom.CompilationUnit lohrCompilationUnit) {
		configureGenerators();
		configurePreProcessors();
		
		_source= lohrCompilationUnit;
		
		for (LohrPreProcessor preProcessor:_preprocessors) {
			preProcessor.preprocess(this);
		}
		
		for (JavaGenerator generator:_generators) {
			generator.compile(this);
		}
	}
	
	private void configurePreProcessors() {
		
	}

	private void configureGenerators() {
		_generators.add(new DefaultJavaGenerator());
	}
	
	public AST getAST() {
		return _ast;
	}

	public lohr.lang.dom.CompilationUnit getSource() {
		return _source;
	}
	
	public void addGenerated(org.eclipse.jdt.core.dom.CompilationUnit generatedUnit) {
		if (!_generated.contains(generatedUnit))
			_generated.add(generatedUnit);
	}
	
	public Collection<org.eclipse.jdt.core.dom.CompilationUnit> getGenerated() {
		return _generated;
	}
	
	
	public static TypeBinding getTypeBinding(TypeReference typeReference) {
		throw new RuntimeException("unfinished");
	}
}
